home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr26 / memspd.zip / MEMSPD.C next >
C/C++ Source or Header  |  1993-03-31  |  13KB  |  342 lines

  1. /*M* memspd - memory speed checker */
  2. /*O*P R */
  3.  
  4.  
  5. extern int           prver;
  6. extern int           ver;
  7. extern int           IORDB(unsigned);
  8. extern int           IORDW(unsigned);
  9. extern int           LOAD(unsigned,unsigned,unsigned);
  10. extern int           LOADEM(long unsigned,unsigned,unsigned);
  11. extern int           LOADH(unsigned,unsigned,unsigned);
  12. extern int           STORB(void);
  13. extern int           STORW(void);
  14. static int           diff(int i);
  15. static void          dispmem(unsigned long base,unsigned long last,
  16.                              unsigned cach[],unsigned ncach[]);
  17. static unsigned      getopt(void);
  18.  
  19. #define maxports 10
  20. static unsigned      portb[maxports+1] = { 0 };
  21. static unsigned      portw[maxports+1] = { 0 };
  22.  
  23. static unsigned      nopt;
  24. static char         *popt;
  25. #define maxopt 8
  26. static char          opt[maxopt+2];
  27.  
  28. #define optbyt  1
  29. #define optwrd  2
  30. #define opt386  3
  31. #define optques 4
  32. static char optkwt[] = {
  33.           7,3,optbyt,    3,'I','O','B',
  34.           7,3,optwrd,    3,'I','O','W',
  35.           7,3,opt386,    3,'3','8','6',
  36.           5,1,optques,   1,'?',
  37.           0 };
  38.  
  39. void USR(void)
  40.           {
  41.           char            flg386;
  42.           int             i,j,cnt;
  43.           unsigned        seg,port;
  44.           unsigned        cach[3],ncach[3];
  45.           unsigned       *ptbl;
  46.           unsigned        memlow,memhigh;
  47.           long unsigned   base,last;
  48.  
  49.           {
  50.           char            bfr[12];
  51.           unsigned        prversion;
  52.           unsigned        version;
  53.           /**/
  54.           prversion = &prver;
  55.           version = &ver;
  56.           if ( prversion )
  57.                sprintf(bfr,"-%x",prversion);
  58.           else
  59.                bfr[0] = 0;
  60.           printf("MEMSPD %x.%02x%s\n\n",version >> 8,version & 0xFF,bfr);
  61.           }
  62.           flg386 = 0;
  63.  
  64.           memlow = MEML();
  65.           memhigh = MEMH();
  66.  
  67.           popt = 0x80;
  68.           nopt = *(popt++);        /* # bytes of options */
  69.           ptbl = 0;
  70.           while ( nopt )
  71.                {
  72.                if ( getopt() )
  73.                     {
  74.                     if ( opt[1] != '/' && opt[1] != '-' )
  75.                          {
  76.                          if ( ptbl == 0 )
  77.                               {
  78. printf("Illegal option %s\n",opt+1);
  79. opts:
  80. printf("Legal options are:\n");
  81. printf("  -386  -  4-byte memory accesses and test all ext mem (386/486 CPU)\n");
  82. printf("  -IOB  xxx  [xxx ...]  -  do byte reads from the specified I/O ports\n");
  83. printf("  -IOW  xxx  [ xxx ...]  -  do word reads from the specified I/O ports\n");
  84. printf("   where xxx are hex I/O port addresses.\n");
  85. printf("  -?  -  print this message\n");
  86. printf("\n");
  87. printf("For each area of memory, two tests are done using byte accesses, two using\n");
  88. printf("word (16-bit) accesses, and if -386 was specified two using double-word\n");
  89. printf("(32-bit) accesses.  For each pair, the first is done maximizing the chance\n");
  90. printf("that all data accessed will be in the CPU cache and the second is done\n");
  91. printf("minimizing the chance.  If the timings differ by more than .04 both are\n");
  92. printf("printed separated by a dash to give a rough idea of the speed improvement\n");
  93. printf("due to the CPU cache.  Dual-ported memory, such as on a video card, may show\n");
  94. printf("two numbers even though the memory is not cached because of delays caused\n");
  95. printf("by the board accessing the memory internally.  The best way to see the\n");
  96. printf("effects of the cache is to run MEMSPD twice, once with the cache enabled\n");
  97. printf("and again with it disabled, since MEMSPD is not always able to entirely\n");
  98. printf("bypass the cache.  For accurate results do not run with any memory manager.\n");
  99.                               return;
  100.                               }
  101.                          if ( ptbl[0] >= maxports )
  102.                               {
  103.                               printf("More than 10 ports specified.\n");
  104.                               return;
  105.                               }
  106.                          i = 0;
  107.                          j = 0;
  108.                          while ( j < opt[0] )
  109.                               {
  110.                               char chr;
  111.                               /**/
  112.                               chr = opt[++j];
  113.                               if ( chr >= '0' && chr <= '9' )
  114.                                    chr -= '0';
  115.                               else
  116.                                    if ( chr >= 'A' && chr <= 'F' )
  117.                                         chr += 10 - 'A';
  118.                                    else
  119.                                         if ( chr >= 'a' && chr <= 'f' )
  120.                                              chr += 10 - 'a';
  121.                                         else
  122.                                              {
  123.                                              printf("Illegal hex digit %c\n",chr);
  124.                                              return;
  125.                                              }
  126.                               if ( i & 0xF000 )
  127.                                    {
  128.                                    printf("Hex number too large - %s\n",opt+1);
  129.                                    return;
  130.                                    }
  131.                               i <<= 4;
  132.                               i += chr;
  133.                               }
  134.                          ptbl[++ptbl[0]] = i;
  135.                          }
  136.                     else
  137.                          {
  138.                          opt[1] = opt[0] - 1;
  139.                          switch ( U0KWSR(opt+1,optkwt) )
  140.                            {
  141.                            case optbyt:
  142.                               ptbl = portb;
  143.                               break;
  144.                            case optwrd:
  145.                               ptbl = portw;
  146.                               break;
  147.                            case opt386:
  148.                               flg386 = 1;
  149.                               ptbl = 0;
  150.                               break;
  151.                            case optques:
  152.                               goto opts;
  153.                            default:
  154.                               printf("Unknown option %s\n",opt+2);
  155.                               goto opts;
  156.                            }
  157.                          }
  158.                     }
  159.                }
  160.  
  161.           printf("Type 'MEMSPD -?' for a list of legal options\n\n");
  162.  
  163.           printf("Read Memory (rep lods):\n");
  164.           printf(" %dK conventional memory\n",memlow);
  165.           seg = cach[0] = ncach[0] = cach[2] = ncach[2] = 0;
  166.           do
  167.                {
  168.                i = LOAD(seg,1,0);
  169.                j = LOAD(seg,0,0);
  170.                if ( diff(i-ncach[0]) || diff(j-cach[0]) )
  171.                     {
  172.                     if ( seg )
  173.                          dispmem(base,last,cach,ncach);
  174.                     base = ((long unsigned)seg) << 4;
  175.                     ncach[0] = i;
  176.                     cach[0] = j;
  177.                     ncach[1] = LOAD(seg,1,1);
  178.                     cach[1] =  LOAD(seg,0,1);
  179.                     if ( flg386 )
  180.                          {
  181.                          ncach[2] = LOAD(seg,1,2);
  182.                          cach[2]  = LOAD(seg,0,2);
  183.                          }
  184.                     }
  185.                last = ((long unsigned)seg) << 4;
  186.                if ( (seg >> 6) < memlow )
  187.                     {
  188.                     seg += 0x1000;
  189.                     last += 0x10000;
  190.                     }
  191.                else
  192.                     {
  193.                     seg += 0x400;
  194.                     last += 0x4000;
  195.                     }
  196.                } while ( seg );
  197.           dispmem(base,last,cach,ncach);
  198.           printf(" %dK extended memory\n",memhigh);
  199.           cach[1] = ncach[1] = cach[2] = ncach[2] = 0;
  200.           if ( memhigh )
  201.                {
  202.                if ( ADDRH() )
  203.                     printf("Can't address extended mem\n");
  204.                else
  205.                     if ( flg386 == 0 )
  206.                          {
  207.                          for ( i=0; i<2; i++ )
  208.                               {
  209.                               ncach[i] = LOADH(0,1,i);
  210.                               cach[i] = LOADH(0,0,i);
  211.                               }
  212.                          dispmem(0x10_0000,0x10_1000,cach,ncach);
  213.                          }
  214.                     else
  215.                          {
  216.                          long curmem;
  217.                          /**/
  218.                          curmem = 0x10_0000;
  219.                          cach[0] = ncach[0] = cach[2] = ncach[2] = 0;
  220.                          while ( memhigh )
  221.                               {
  222.                               i = LOADEM(curmem,1,0);
  223.                               j = LOADEM(curmem,0,0);
  224.                               if ( diff(i-ncach[0]) || diff(j-cach[0]) )
  225.                                    {
  226.                                    if ( curmem != 0x10_0000 )
  227.                                         dispmem(base,last,cach,ncach);
  228.                                    base = curmem;
  229.                                    ncach[0] = i;
  230.                                    cach[0] = j;
  231.                                    ncach[1] = LOADEM(curmem,1,1);
  232.                                    cach[1] =  LOADEM(curmem,0,1);
  233.                                    ncach[2] = LOADEM(curmem,1,2);
  234.                                    cach[2]  = LOADEM(curmem,0,2);
  235.                                    }
  236.                               curmem += 0x1_0000;
  237.                               last = curmem;
  238.                               memhigh -= (memhigh > 64) ? 64 : memhigh;
  239.                               }
  240.                          dispmem(base,last,cach,ncach);
  241.                          }
  242.                }
  243.  
  244.           if ( cnt = portb[0] )
  245.                {
  246.                printf("\nRead Byte I/O Port (rep insb):\n");
  247.                j = 0;
  248.                while ( cnt > j )
  249.                     {
  250.                     port = portb[++j];
  251.                     i = IORDB(port);
  252.                     printf(" Port %3x  %3u.%02u usec\n",port,i/100,i%100);
  253.                     }
  254.                i = STORB();
  255.                printf(" Mem store %3u.%02u usec (rep stosb)\n",i/100,i%100);
  256.                }
  257.           if ( cnt = portw[0] )
  258.                {
  259.                printf("\nRead Word I/O Port (rep insw):\n");
  260.                j = 0;
  261.                while ( cnt > j )
  262.                     {
  263.                     port = portw[++j];
  264.                     i = IORDW(port);
  265.                     printf(" Port %3x  %3u.%02u usec\n",port,i/100,i%100);
  266.                     }
  267.                i = STORW();
  268.                printf(" Mem store %3u.%02u usec (rep stosw)\n",i/100,i%100);
  269.                }
  270.  
  271.           return;
  272.  
  273.           }
  274.  
  275.  
  276.  
  277. static int diff(int i)
  278.           {
  279.  
  280.           if ( i < 0 )
  281.                i = -i;
  282.           return (i <= 4) ? 0 : 1;
  283.  
  284.           }
  285.  
  286.  
  287.  
  288. static void dispmem(long unsigned base,
  289.                     long unsigned last,
  290.                     unsigned cach[],
  291.                     unsigned ncach[])
  292.           {
  293.           unsigned i,off;
  294.           char bfr[120];
  295.           char *sep;
  296.           static char *siz[3] = { "byte", "word", "dwrd" };
  297.  
  298.  
  299.           off = sprintf(bfr," %x%04x - %x%04x ",(unsigned)(base>>16),
  300.             (unsigned)(base&0xFFFF),(unsigned)((last-1)>>16),(unsigned)((last-1)&0xFFFF));
  301.  
  302.           sep = "";
  303.           for ( i=0; i<3; i++ )
  304.                {
  305.                if ( cach[i] )
  306.                     {
  307.                     off += sprintf(bfr+off,"%s%s %u.%02u",
  308.                       sep,siz[i],cach[i]/100,cach[i]%100);
  309.                     if ( diff(cach[i]-ncach[i]) )
  310.                          off += sprintf(bfr+off,"-%u.%02u",
  311.                            ncach[i]/100,ncach[i]%100);
  312.                     sep = ", ";
  313.                     }
  314.                }
  315.           printf("%s\n",bfr);
  316.           return;
  317.  
  318.           }
  319.  
  320.  
  321.  
  322. static unsigned getopt(void)
  323.           {
  324.  
  325.           opt[0] = 0;
  326.           while ( nopt )
  327.                {
  328.                if ( *popt <= ' ' )
  329.                     if ( opt[0] )
  330.                          goto done;
  331.                     else
  332.                          goto next;
  333.                if ( opt[0] < maxopt )
  334.                     opt[++opt[0]] = *popt;
  335. next:          popt++;
  336.                nopt--;
  337.                }
  338.  
  339. done:     opt[opt[0]+1] = 0;
  340.           return opt[0];
  341.           }
  342.